#include "ProjectHeader.h"
#include "UIElement.h"

#pragma region SetterMethods
UIElement::UIElement()
{
	_fgDirty = true;
	_bgDirty = true;
}

void UIElement::SetBackground(texCoord2f backgroundTexture)
{
	_backgroundTexture = backgroundTexture;
	_bgDirty = true;
}

void UIElement::SetPos(vertex2f position)
{
	SetAreaRectangle(position);
	_fgDirty = true;
	_bgDirty = true;
}

void UIElement::SetSize(vertex2f size)
{
	_size = size;
	SetAreaRectangle(_area.btmLft);
	_fgDirty = true;
	_bgDirty = true;
}

void UIElement::SetStat(int UIManRegisteredStat)
{
	_registeredStat = UIManRegisteredStat;
	_lastStatValue = _UIManStatGetter(_registeredStat);
}

void UIElement::SetUIManDelegate(UIStat_delegate UIManStatGetter)
{
	_UIManStatGetter = UIManStatGetter;
}
#pragma endregion

#pragma region DrawMethods

bool UIElement::DrawBackground(std::vector<vertex> *VBOVec, const std::map<int,texCoord2f> &texMap, GLuint currentTex)
{
	if(VBOVec == NULL){return !_bgDirty;}
	if(currentTex == _backgroundTexture.TexIndex)
	{
		DrawRectangle(VBOVec, _area, _backgroundTexture, 3.0f);	//HACK depth
		_bgDirty = false;
		return true;
	}
	return false;
}

bool UIElement::DrawForeground(std::vector<vertex> *VBOVec, const std::map<int,texCoord2f> &texMap, GLuint currentTex)
{
	if(VBOVec == NULL){return false;}	//Never need to redraw foreground; it's empty.
	return false;						//Nothing added
}

bool UIElement::Draw(std::vector<vertex> *VBOVec, const std::map<int,texCoord2f> &texMap, GLuint currentTex)
{
	return DrawBackground(VBOVec, texMap, currentTex);
}

void UIElement::DrawRectangle(std::vector<vertex> * VBOVec, rectangle Rectangle, texCoord2f Texture, GLfloat Depth)
{
	VBOVec->reserve(6);	//That's how many verts we're adding. If the capacity is greater than this, nothing changes.
	vertex TempVert[4];

	for(int i = 0; i < 4; i++){TempVert[i].normal.z = 1.0f; TempVert[i].position.z = Depth;}
	//Sets the normals to forwards and the depth to the passed Depth for every vertex

	// This is how the four elements of TempVert line up to the four corners of the rectangle
	//	3-------2
	//	|		|
	//	0-------1
	//	And this is how it's tesselated
	//	3--2   2
	//	| /  / |
	//	0   0--1
	//	So, the final order in the VBO is 0,1,2,0,2,3


	//PART 1: SET THE TEXTURE COORDS
	TempVert[0].texCoord = Texture.btmLft;
	TempVert[1].texCoord = Texture.btmRgt;
	TempVert[2].texCoord = Texture.topRgt;
	TempVert[3].texCoord = Texture.topLft;

	//PART 2: SET THE VERTEX POSITIONS
	TempVert[0].position.x = _area.btmLft.u + Rectangle.btmLft.u * _size.u;
	TempVert[0].position.y = _area.btmLft.u + Rectangle.btmLft.v * _size.v;

	TempVert[1].position.x = _area.btmLft.u + Rectangle.btmRgt.u * _size.u;
	TempVert[1].position.y = _area.btmLft.u + Rectangle.btmRgt.v * _size.v;

	TempVert[2].position.x = _area.btmLft.u + Rectangle.topRgt.u * _size.u;
	TempVert[2].position.y = _area.btmLft.u + Rectangle.topRgt.v * _size.v;

	TempVert[3].position.x = _area.btmLft.u + Rectangle.topLft.u * _size.u;
	TempVert[3].position.y = _area.btmLft.u + Rectangle.topLft.v * _size.v;

	//PART 3: PUT IT ALL IN THE VBO
	VBOVec->push_back(TempVert[0]);
	VBOVec->push_back(TempVert[1]);
	VBOVec->push_back(TempVert[2]);
	VBOVec->push_back(TempVert[0]);
	VBOVec->push_back(TempVert[2]);
	VBOVec->push_back(TempVert[3]);
}

void UIElement::SetAreaRectangle(vertex2f position)
{
	_area = CalculateRectangle(position, _size);
}
#pragma endregion

rectangle UIElement::CalculateRectangle(vertex2f position, vertex2f size)
{
	rectangle tempRectangle;

	tempRectangle.btmLft   = position;
	
	tempRectangle.btmRgt.u = position.u + size.u;
	tempRectangle.btmRgt.v = position.v;

	tempRectangle.topRgt.u = position.u + size.u;
	tempRectangle.topRgt.v = position.v + size.v;

	tempRectangle.topLft.u = position.u;
	tempRectangle.topLft.v = position.v + size.v;

	return tempRectangle;
}

bool UIElement::StatValueHasChanged()
{
	int tempStatValue;
	tempStatValue = _UIManStatGetter(_registeredStat);
	if(tempStatValue != _lastStatValue)
	{
		_lastStatValue = tempStatValue;
		return true;
	}
	return false;
}